import { CloseOutlined } from "@ant-design/icons";
import { Button, Spin, Tooltip } from "antd";
import dayjs from "dayjs";
import * as Echarts from "echarts";
import EChartsReact from "echarts-for-react";
import {
  forEach,
  uniqBy,
  indexOf,
  throttle,
  sortBy,
  find,
  cloneDeep,
  slice,
  map,
  uniq,
  concat,
  head,
  pull,
  last,
  take,
  countBy,
  values,
  max,
} from "lodash";
import { eq, findIndex, debounce } from "lodash-es";
import { useState, useEffect, useRef } from "react";

// @ts-ignore
import ChartItemOptions from "./chartItemOptions";
import { chartShifting, setStateBackgrounColor } from "./utils";

import Remove from "~/components/Remove";
import { useAnalysisTask } from "~/components/Visualization/store/useTaskState";
import { useSystemConfig } from "~/hooks/systemConfig/use-systemConfig-api";
import { ParamQueryInput, ParamType } from "~/modules/api-server/types";
import {
  formatDateTime,
  formatDateTimeSS,
} from "~/modules/shared/utils/common";
import { axisData, Scheduler } from "~/modules/worker/schedule";
import { useStoreRecord } from "~/modules/worker/store/use-StoreRecord";
import { useRemotePathList } from "~/modules/worker/use-remote-path";
import { Chart, ChartType, ChartItem } from "~/modules/workspace/models";
import { useWorkSpace } from "~/modules/workspace/store/use-workspace";
import eventBus from "~/utils/event";
interface Props {
  onDelTask: Function;
  onSetSetDelChart: Function;
}
const ChartItem1 = (props: Props) => {
  // 获取工作区配置数据
  const { workSpace } = useWorkSpace();
  const { analysisTask } = useAnalysisTask();
  const { has, add } = useStoreRecord();
  const { loadResult } = useRemotePathList();
  // 图表数据
  const [list, setData] = useState<{ [propName: string]: any }>({});
  // 数据加载状态
  const [isLoading, setIsLoading] = useState<boolean>(false);
  // 工作区高度
  const [workerHeight, setWorkHeight] = useState<number>(600);
  // 单个图高度
  const [chartItemHeight, setChartItemHeight] = useState<number>(
    Number(workSpace.setting.chartsHeight)
  );

  // 单图上下间距
  const [spacing] = useState<number>(60);
  // 获取系统设置超时时间
  const { load }: any = useSystemConfig();
  const dataZoom = useRef<{
    startValue: number;
    endValue: number;
  }>({
    startValue: 0,
    endValue: 0,
  });
  const [dataZoomMax, setDataZoomMax] = useState(0);

  // x轴显示的data
  const legend: any[] = [];
  let xAxis: any[] = [];
  const yAxis: any[] = [];
  const grid: any[] = [];
  const xAxisIndexZoom: number[] = [0];
  const series: any[] = [];
  useEffect(() => {
    setChartItemHeight(Number(workSpace.setting.chartsHeight));
    const H: number =
      workSpace.splitCharts.length *
        (Number(workSpace.setting.chartsHeight) + spacing) +
      50;
    setWorkHeight(H);
  }, [workSpace.setting.chartsHeight, workSpace.splitCharts.length]);

  useEffect(() => {
    const params: ParamQueryInput[] = [];
    forEach(workSpace.splitCharts, (item: ChartItem) => {
      forEach(item.data, (m: Chart) => {
        const paramKey =
          m.paramType == ParamType.Field ? m.title : m.expression;
        params.push({
          expr: paramKey,
          type: m.paramType,
        });
      });
    });
    const getData = async () => {
      setIsLoading(true);
      const { data } = await load({
        variables: {
          keys: ["quiver_get_data_timeout"],
        },
      });
      setTimeout(data);
      await Scheduler.get({
        flightIds: analysisTask.flights,
        params: uniqBy(params, "expr"),
        has,
        add,
        loadResult,
      });
      setDataZoomMax(max(map(values(Scheduler.datas), "length"))!);
      setData(Scheduler.datas);
      setIsLoading(false);
      Scheduler.clear();
    };

    if (
      analysisTask.flights.length > 0 &&
      params.length > 0 &&
      !Scheduler.loading
    ) {
      getData();
    }
  }, [workSpace.splitCharts, workSpace.splitCharts.length]);

  // 获取状态量背景色时间段
  const [markArea, setMarkArea] = useState<any>();
  useEffect(() => {
    const stateParamData =
      Scheduler.datas[workSpace.setting.stateQuantityParams];
    const state = workSpace.setting.setBgByStateQuantity;
    const stateParam = workSpace.setting.stateQuantityParams;
    setMarkArea(setStateBackgrounColor(stateParamData, state, stateParam));
  }, [
    workSpace.setting.setBgByStateQuantity,
    workSpace.setting.stateQuantityParams,
    Scheduler.datas,
  ]);

  const emitDateRange = (data: any) => {
    eventBus.emit("dataList", data);
    eventBus.emit("chartParamsStatistics", {
      startTime: formatDateTime(data.startTime),
      endTime: formatDateTime(data.endTime),
    });
  };
  const throttleq = throttle(emitDateRange, 1500);
  const onclick = {
    dataZoom: (e: any, c: any) => {
      const startIndex: number = c.getOption().dataZoom[0].startValue;
      const endIndex: number = c.getOption().dataZoom[0].endValue;
      const times: string[] = uniq(
        concat(axisData.data, axisData.offsetAxisData)
      );
      dataZoom.current = { startValue: startIndex, endValue: endIndex };
      const start = formatDateTimeSS(times[startIndex]);
      const end = formatDateTimeSS(times[endIndex]);
      const arr = sortBy([start, end]);
      throttleq({ startTime: arr[0], endTime: arr[1] });
    },
    restore: () => {
      const n: number = 0;
      let param: any;
      forEach(Object.keys(list), (k) => {
        if (list[k].length > n) {
          param = list[k];
        }
      });
      eventBus.emit("dataList", { startIndex: "", endIndex: "" });
      eventBus.emit("chartParamsStatistics", {
        startTime: param && param[0] ? formatDateTime(param[0].systime) : "",
        endTime:
          param && param[param.length - 2]
            ? formatDateTime(param[param.length - 2].systime)
            : "",
      });
      dataZoom.current = {
        startValue: 0,
        endValue:
          uniq(concat(axisData.data, axisData.offsetAxisData)).length - 1,
      };
    },
  };

  const setDebounce = debounce((params: any) => {
    const currIndex = findIndex(
      Object.values(Scheduler.datas)[0],
      (item: any) => {
        return eq(
          dayjs(item.systime).format("YYYY-MM-DD HH:mm:ss"),
          dayjs(params[0].axisValueLabel).format("YYYY-MM-DD HH:mm:ss")
        );
      }
    );
    eventBus.emit("pagination", {
      currIndex,
    });
  }, 500);

  // 设置超时时间
  const setTimeout = (timeout: any) => {
    const settings = timeout?.dictionarySetting ?? [];
    const init_get_data_timeout: number =
      find(settings, (s) => {
        return s.item == "quiver_get_data_timeout";
      })?.content?.data ?? 20;
    Scheduler.timeout = init_get_data_timeout * 1000;
  };
  if (Object.keys(Scheduler.datas ?? []).length > 0) {
    const n: number = 0;
    let param: any;
    forEach(Object.keys(Scheduler.datas), (k) => {
      if (Scheduler.datas[k].length > n) {
        param = Scheduler.datas[k];
        axisData.data = uniq(
          concat(
            axisData.data,
            map(Scheduler.datas[k], (obj) => {
              if (obj.systime) {
                return formatDateTimeSS(obj.systime);
              } else {
                return "";
              }
            })
          )
        );
      }
    });
  }
  useEffect(() => {
    dataZoom.current = {
      startValue: 0,
      endValue: dataZoomMax,
    };
    console.log(dataZoom.current.endValue);
  }, [dataZoomMax]);
  const supplementaryData = (
    seriesData: (string | number)[][],
    axisTotalData: string[]
  ) => {
    if (seriesData.length < axisTotalData.length - 1) {
      axisTotalData = sortBy(axisTotalData, (s) => s);
      // @ts-ignore
      const a = new Map(seriesData);
      const b = new Map();
      axisTotalData.forEach((item) => {
        b.set(item, a.get(item) ?? null);
      });
      return Array.from(b);
    }
    return seriesData;
  };

  forEach(workSpace.splitCharts, (item: ChartItem, index: number) => {
    // Y轴配置
    yAxis.push({
      gridIndex: index,
      axisLine: {
        show: true,
      },
      axisLabel: {
        fontSize: 9,
        formatter: (value: any, index: number) => {
          if (value >= 1000) {
            return value / 1000 + "K";
          } else if (value >= 10000) {
            return value / 10000 + "W";
          } else {
            return value;
          }
        },
      },
      min: item.lowerLimit ? Number(item.lowerLimit) : null,
      max: item.upperLimit ? Number(item.upperLimit) : null,
    });
    // 图表布局
    const data_keys_lens = workSpace.splitCharts.length;
    grid.push({
      top: `${50 + (chartItemHeight + spacing) * index}`,
      right: "30",
      bottom: `${
        (data_keys_lens - (index + 1)) * (chartItemHeight + spacing) + 60
      }`,
      left: "65",
    });
    // 与滑动条联动的图
    xAxisIndexZoom.push(index);

    forEach(item.data, (m: Chart, i: number) => {
      const paramKey = m.paramType == ParamType.Field ? m.title : m.expression;
      const chartParamsData =
        (Scheduler.datas &&
          Scheduler.datas[paramKey] &&
          cloneDeep(Scheduler.datas[paramKey])) ||
        [];
      const seriesData = chartShifting(chartParamsData, item, paramKey);
      legend.push(m.title);
      series.push({
        name: m.title,
        showSymbol: false,
        data: supplementaryData(seriesData, axisData.data),
        xAxisIndex: index,
        yAxisIndex: index,
        markArea: workSpace.setting.setBgByStateQuantity
          ? {
              data: map(
                slice(markArea, 0, markArea?.length - 1),
                (m: string[], index) => {
                  return [
                    {
                      xAxis: m[0],
                      itemStyle: {
                        color:
                          workSpace.setting.backgroundColors[
                            (index + 1) % 2 === 0 ? 1 : 0
                          ],
                        opacity: 0.8,
                      },
                    },
                    {
                      xAxis: m[1],
                    },
                  ];
                }
              ),
            }
          : {},
        type:
          item.chartType === ChartType.LINEAREA
            ? ChartType.LINE
            : item.chartType,
        areaStyle:
          item.chartType === ChartType.LINEAREA ? { color: m.color } : null,
        lineStyle:
          item.chartType === ChartType.LINE ? { color: m.color } : null,

        itemStyle:
          item.chartType === ChartType.SCATTER ? { color: m.color } : null,

        symbolSize: 5,
        large: true,
      });
    });
  });
  // X轴配置
  xAxis = map(workSpace.splitCharts, (item: ChartItem, index: number) => {
    return {
      type: "category",
      axisLabel: {
        formatter(value: string | number | Date) {
          return (value && dayjs(value).format("MM-DD HH:mm:ss")) || value;
        },
      },
      data: pull(
        sortBy(uniq(concat(axisData.data, axisData.offsetAxisData))),
        ""
      ),
      boundaryGap: ["1%", "1%"],
      gridIndex: index ?? "",
    };
  });

  if (xAxis.length === 0) {
    return <div> </div>;
  }

  const firstSeries = take(series);
  const option = {
    legend: {
      data: legend,
      top: "bottom",
    },

    tooltip: {
      trigger: "axis",
      formatter(params: any) {
        setDebounce(params);
        const axisValue = params[0].axisValueLabel;
        const marker = params[0].marker;
        const seriesName = params[0].seriesName;
        const seriesValue = params[0].value[1];
        return `
                <div>${axisValue}</div>
                <div>${marker}${seriesName} ${seriesValue} </div>
            `;
      },
    },
    xAxis,
    yAxis,
    grid,
    toolbox: {
      top: "-5%",
      feature: {
        dataZoom: {
          yAxisIndex: "none",
          title: {
            zoom: "区域缩放",
            back: "缩放还原",
          },
        },
        restore: {
          title: "还原",
        },
      },
    },
    dataZoom: [
      {
        type: "slider",
        xAxisIndex: xAxisIndexZoom, // 显示 0 1 的数据，这个要加，不加的话，悬浮提示就会出问题
        show: false,
        showDetail: true,
        top: "",
        left: "90",
        right: "30",
        startValue: dataZoom.current.startValue,
        endValue:
          dataZoom.current.endValue === 0
            ? dataZoomMax
            : dataZoom.current.endValue,
      },
      {
        type: "select",
        xAxisIndex: xAxisIndexZoom,
      },
    ],
    series,
  };
  console.log(option);
  const optionZoom = {
    xAxis: xAxis.map((x) => {
      return {
        ...x,
        show: false,
      };
    }),
    yAxis: yAxis.map((x) => {
      return {
        ...x,
        show: false,
      };
    }),
    grid: grid.map((x) => {
      return {
        ...x,
        show: false,
      };
    }),
    toolbox: {
      top: "3",
      left: "3",
      feature: {
        dataZoom: {
          yAxisIndex: "none",
          title: {
            zoom: "区域缩放",
            back: "缩放还原",
          },
        },
        restore: {
          title: "还原",
        },
      },
    },
    dataZoom: [
      {
        type: "slider",
        xAxisIndex: xAxisIndexZoom, // 显示 0 1 的数据，这个要加，不加的话，悬浮提示就会出问题
        show: true,
        showDetail: true,
        top: "",
        left: "90",
        right: "30",
        startValue: dataZoom.current.startValue,
        endValue:
          dataZoom.current.endValue === 0
            ? dataZoomMax
            : dataZoom.current.endValue,
      },
      {
        type: "select",
        xAxisIndex: xAxisIndexZoom,
      },
    ],
    series: firstSeries,
  };

  if (series[0] && series[0]["data"] && series[0]["data"].length > 0) {
    eventBus.emit("chartParamsStatistics", {
      startTime: formatDateTime(head(head(series[0]["data"]))),
      endTime: head(last(series[0]["data"]))
        ? formatDateTime(head(last(series[0]["data"])))
        : formatDateTime(head(series[0]["data"][series[0]["data"].length - 2])),
    });
  }
  eventBus.emit("dataList", { startTime: "", endTime: "" });
  // @ts-ignore
  const [chartDataEvent, setChartDataEvent] = useState<Echarts>();
  // @ts-ignore
  const [chartDataZoomEvent, setChartDataZoomEvent] = useState<Echarts>();
  if (chartDataEvent && chartDataZoomEvent) {
    Echarts.connect([
      chartDataZoomEvent.getEchartsInstance(),
      chartDataEvent.getEchartsInstance(),
    ]);
  }
  const selectCHartStyle = {
    width: "3px",
    backgroundColor: "#1890ff",
  };
  const notSelectCHartStyle = {
    width: "3px",
  };

  // 已选择的图表
  const [selectChart, setSelectChart] = useState<{
    name: string;
    index: number;
  }>({
    name: "",
    index: 0,
  });
  const [isData, setIsData] = useState<boolean>(false);

  eventBus.on("selectChart", (value: any) => {
    value.key === "0" ? setIsData(true) : setIsData(false);
    setSelectChart({ name: value.name, index: value.index });
  });

  const onSelectChartName = (chart: ChartItem, index: number) => {
    eventBus.emit("switchEcharts", { chart, index });
    setSelectChart({ name: chart.name, index });
    setIsData(false);
  };
  // 获取删除弹框的dom
  const removeRef = useRef();
  // 删除chart
  const [delText, setDelText] = useState<string>("");
  const chartItemName = workSpace.splitCharts.map(
    (chart: ChartItem, index: number) => {
      return (
        <div
          key={index}
          className={`w-65px z-1 flex  text-center  chart-list-chart-name-list-item ${
            chart.IsTop && "chart-list-chart-name-list-item-IsTop"
          }`}
          style={{
            top: `${
              45 + index * (Number(workSpace.setting.chartsHeight) + 60)
            }px`,
          }}
          onClick={() => onSelectChartName(chart, index)}
        >
          <div
            style={
              chart.name === selectChart.name && index === selectChart.index
                ? selectCHartStyle
                : notSelectCHartStyle
            }
          />
          <Button
            className="w-15px! h-15px! ml-2px chart-list-chart-name-list-item-delBtn"
            type="text"
            icon={<CloseOutlined />}
            onClick={() => {
              setDelText(`是否删除图表 ${chart.name} ？`);
              removeRef.current && (removeRef.current as any).onDelete();
              props.onSetSetDelChart({ name: chart.name, index });
            }}
          />
          <Tooltip title={chart.name}>
            <p
              className=" text-10px truncate pt-5px chart-list-chart-name-list-item-p"
              style={{
                height: `${Number(workSpace.setting.chartsHeight) + 10}px`,
              }}
            >
              {chart.name}
            </p>
          </Tooltip>
        </div>
      );
    }
  );
  return (
    <div id="ChartList" className="pt-16px pr-16px pb-16px pl-0 h-600px!">
      <Spin tip="Loading..." spinning={isLoading}>
        <div className="flex flex-col h-full">
          <div className="h-45px w-full! overflow-hidden">
            <EChartsReact
              ref={(e) => {
                // @ts-ignore
                setChartDataZoomEvent(e);
              }}
              notMerge={false}
              lazyUpdate
              option={optionZoom}
              style={{ height: `${workerHeight}px` }}
              onEvents={onclick}
            />
          </div>
          <div style={{ height: `500px` }} className="overflow-y-scroll">
            <div className="chart-list-chart-name-list">
              <ChartItemOptions />
            </div>
            <EChartsReact
              ref={(e) => {
                // @ts-ignore
                setChartDataEvent(e);
              }}
              notMerge={false}
              lazyUpdate
              option={option}
              style={{ height: `${workerHeight}px` }}
              onEvents={onclick}
            />
          </div>
        </div>
      </Spin>
      <Remove ref={removeRef} delText={delText} onDelTask={props.onDelTask} />
    </div>
  );
};

export default ChartItem1;
